var Core = require("core.js");
var Tool = require("tool.js");
var RequestHttps = require("request_https.js");
var Log = require("core_log.js");
var UserInfo = require("privacy_userInfo.js");

/**
 * 得到登录标志
 */
function getLoginFlag() {
  return wx.getStorageSync('loginFlag');
}

function getLoginSkey() {
  return wx.getStorageSync('loginSkey');
}

/**
 * 判断登录
 * 
 * @调用1 isLogin() 不作服务器登录检查
 * @调用2 isLogin(_hostname, _port, _path, _isOkCallback) 作服务器登录检查
 *      
 * @_isOkCallback(res) 调用服务器，如果成功返回 true 则调用 resolve, 否则调用 reject
 * 
 * @resolve() 没有 reject 调用, 所以不做作 catch 操作
 * @reject([res, isLoginFlag:Boolean]) 只有在调用服务器的返回结果中才有res参数值, 否则res为null
 * 
 * @session_key 过期时间：
    下面是我得出来的经验值 不保证完全正确：
      1. 当用户删除小程序后会失效
      2. 用户没有删除小程序并且没有重新进行 login 默认30天左右
      3. 当用户30天没有打开小程序则会失效
      4. 当用户在有效期内使用了小程序，有效时间将会重新计算
 *
 */
function isLogin(_hostname, _port, _path, _isOkCallback){
  var logCallerName = isLogin.name;
  // 参数处理
  var useServerFlag = true;
  if (Core.Type.IsFunction(_hostname)) {
    _isOkCallback = _hostname;
    useServerFlag = false;
  }
  // 第一步：检查本地 storage 中是否有登录态标识
  if (!getLoginFlag()) {
    Log.debug(logCallerName, '没有登录标志')
    return Promise.resolve([null, false]);
  }
  // 第二步：检查 session_key 是否过期
  // 文档 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.checkSession.html
  return new Promise(function (resolve, reject){
      wx.checkSession({
        // session_key 有效
        success: function () {
          Log.debug(logCallerName, 'session_key有效');
          // 第三步：向服务器发送登录验证请求
          if (useServerFlag) {
            RequestHttps
              .getRequest(_hostname, _port, _path)
              .then(function (res) {
                Log.debug(logCallerName, '服务器判断登录,成功获取到结果后返回数据, res:', res)
                // 处理登录成功后返回数据
                if (_isOkCallback(res) === true) {
                  Log.debug(logCallerName, '服务器判断结果为[已登录], res:', res);
                  // 成功回调
                  resolve([res, true])
                } else {
                  Log.debug(logCallerName, '服务器判断结果为[未登录], res:', res);
                  resolve([res, false]);
                }
              })
              .catch(function (res) {
                Log.error(logCallerName, '服务器判断登录出错, res:', res);
                // throw new Error("服务器判断登录出错，请稍后再试", res);
                Tool.showInfo('服务器判断登录出错，请稍后再试');
              });
          }else{
            // 成功回调
            resolve([null, true]);
          }
        },
        // session_key 过期
        fail: function () {
          Log.debug(logCallerName, 'session_key过期');
          resolve([null, false]);
        }
      })
    });
}

/**
 * 登录
 * 
 * @设计登录功能时可以参考一下的文档：https://developers.weixin.qq.com/community/develop/doc/000c2424654c40bd9c960e71e5b009
 * 
 * @调用1 login(_hostname, _port, _path, _isOkCallback)
 * @调用2 login(_hostname, _port, _path, _data, _isOkCallback)
 * 
 * @resolve([res, infoRes])
 * @reject() 没有 reject 调用, 所以不做作 catch 操作
 * @_isOkCallback(res) 调用服务器，如果成功返回{flag:true|false, skey:xxx} 则调用 resolve, 否则调用reject
 * 
 */
function login(_hostname, _port, _path, _data, _isOkCallback) {
  var logCallerName = login.name;
  // 参数处理
  if (Core.Type.IsFunction(_data)) {
    _isOkCallback = _data;
    _data = null;
  }
  // 功能调用
  return new Promise(function (resolve, reject) {
      // 第一步：申请微信登录
      requestWXLogin(function (loginRes) {
        // 第二步：获取用户信息
        UserInfo.getUserInfo(
          true,
          function (infoRes) {
            // 第三步：登录服务器
            RequestHttps
              .postRequest(
                _hostname,
                _port,
                _path,
                Object.assign(
                  {
                    code: loginRes.code,                  // 用户临时登录凭证, 有效期五分钟，到后台换取 openId, sessionKey, unionId
                    rawData: infoRes.rawData,             // 用户非敏感信息
                    signature: infoRes.signature,         // 签名
                    encryptedData: infoRes.encryptedData, // 户非敏感信息
                    iv: infoRes.iv                        // 解密算法的向量
                  },
                  _data
                )
              )
              .then(function (res) {
                Log.debug(logCallerName, '登录服务器成功后返回数据, res:', res)
                const result = _isOkCallback(res);
                if (result.flag === true) {
                  resolve([res, infoRes]);
                } else {
                  reject(res);
                }
                // 保存登录信息
                wx.setStorageSync('loginFlag', result.flag);  // true|false
                wx.setStorageSync('loginSkey', result.skey);
              })
              .catch(function (res) {
                Log.error(logCallerName, '登录服务器出错, res:', res);
                Tool.showInfo('登录服务器出错，请稍后再试')
              });
          }
        );
      });
    }); 
}

/**
 * 微信登录
 */
function requestWXLogin(_success){
  var logCallerName = requestWXLogin.name;
  // 登录，文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
  wx.login({
    // 微信登录成功
    success: res => {
      if (res.code) {   // 获取 code 成功
        _success(res);
      } else {          // 获取 code 失败
        Log.error(logCallerName, '调用wx.login获取code失败', res);
        Tool.showInfo('登录失败');
      }
    },
    // 微信登录失败
    fail: function (res) {
      Log.error(logCallerName, '调用wx.login失败', res);
      Tool.showInfo('登录失败');
    }
  })
}

/**
 * 暴露接口
 */
module.exports = {
  login, isLogin,
  getLoginFlag, getLoginSkey
};